package models

import (
	"context"
	"fmt"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

type Person struct {
	Name string `json:"name"`
	Age  int    `json:"age"`
}

func ConnectToMongoDB() (*mongo.Collection, error) {
	// 创建客户端
	client, err := mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017"))
	if err != nil {
		return nil, fmt.Errorf("创建客户端失败: %s", err)
	}

	// 连接到 MongoDB
	err = client.Connect(context.TODO())
	if err != nil {
		return nil, fmt.Errorf("连接错误: %s", err)
	}

	// 选择数据库和集合
	database := client.Database("test")
	collection := database.Collection("homework")

	return collection, nil
}

// 插入数据
func InsertPerson(collection *mongo.Collection, person Person) error {
	_, err := collection.InsertOne(context.TODO(), person)
	if err != nil {
		return fmt.Errorf("插入数据失败: %s", err)
	}
	return nil
}

func FindPersonByName(collection *mongo.Collection, name string) (*Person, error) {
	filter := bson.M{"name": name}
	var person Person
	err := collection.FindOne(context.TODO(), filter).Decode(&person)
	if err != nil {
		if err == mongo.ErrNoDocuments {
			return nil, nil // 没有找到对应的记录，返回nil
		}
		return nil, fmt.Errorf("查找数据失败: %s", err)
	}
	return &person, nil
}

func UpdatePersonAge(collection *mongo.Collection, name string, age int) error {
	filter := bson.M{"name": name}
	update := bson.M{"$set": bson.M{"age": age}}

	_, err := collection.UpdateOne(context.TODO(), filter, update)
	if err != nil {
		return fmt.Errorf("更新数据失败: %s", err)
	}
	return nil
}

func DeletePerson(collection *mongo.Collection, name string) error {
	filter := bson.M{"name": name}

	_, err := collection.DeleteOne(context.TODO(), filter)
	if err != nil {
		return fmt.Errorf("删除数据失败: %s", err)
	}
	return nil
}

func FindWithSelect01(collection *mongo.Collection, selectFields bson.M, filters ...bson.M) ([]Person, error) {
	findOptions := options.Find()
	findOptions.SetProjection(selectFields)

	var filter bson.M
	if len(filters) > 0 {
		filter = filters[0]
	} else {
		filter = bson.M{}
	}

	cursor, err := collection.Find(context.TODO(), filter, findOptions)
	if err != nil {
		return nil, fmt.Errorf("查询数据失败: %s", err)
	}
	defer cursor.Close(context.TODO())

	var results []Person
	for cursor.Next(context.TODO()) {
		var person Person
		err := cursor.Decode(&person)
		if err != nil {
			return nil, fmt.Errorf("解码数据失败: %s", err)
		}
		results = append(results, person)
	}

	if err := cursor.Err(); err != nil {
		return nil, fmt.Errorf("游标错误: %s", err)
	}

	return results, nil
}
